package service

import (
	"context"
	"fmt"
	"github.com/gin-gonic/gin"
	config2 "github.com/go-admin-team/go-admin-core/config"
	"github.com/go-admin-team/go-admin-core/sdk/service"
	"github.com/go-pay/gopay"
	"github.com/go-pay/gopay/wechat/v3"

	"encoding/json"
	payUtils "github.com/wechatpay-apiv3/wechatpay-go/utils"
	"log"
	"net"
	"strings"
	"time"
	"tuowei.com/app/api/service/dto"
	"tuowei.com/pkg/xlog"
)

const AppID, MchId, SerialNo, APIv3Key = "wxf741b8a76b5eed4f", "1533105481", "75D53DE02B5D5F4DBFB0D08CE1352628EF1FB890", "e92028de6429d6e83ed038d9e723ee83"
const PrivateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDFNP5FoCAE1uYj\nirLMoK0jv5JxoLUWxqobqJlENQYWm7FAfqD1JasIrSehWSmcrIJn3hwyRTHSozh/\nLOoTB/TLWBh1jdoLM/TDbP6xRZI/MeGFvMYebGlNHD+Yb9c7Fd0ns3cdWZuIESXb\neJd1fGDGekoJqoxpsdvAMxga0CMlReuuonUp6eVjIXcDe6La9TCjnbC5TiZ/u3BH\nlyBQ+FtupCrP+YuGSh5bfgTlnAop/hBIwY851cjETuUW8xxRIzdsKMSjxPNmPOZK\nfVca6/HyBZ44qxO+UzDJABfJCMwMZ6KZgf5XTO6uQGvs9FSkByqsgyG93fnDVlCI\nkO717oCjAgMBAAECggEBAKDIK+coPfK0Ir4nfs9G0OKsdgEePYZsQpR6STtK38Pe\n/AzRMPmt1FwmkIED6OFL5KY6eFKkB5LscEt/mvgZLIP9NzPgiz1HBu+uFZkCV9Ie\nIPigiAaV7ORpe5AU3y3VDZIox5yuShgNowfksdefqGcpnON0oTYrRDbXcXeq6nyf\nrO3HNScxMLt3dKqmYufBJfyJ5ywGI0GUhoOV6yNO5Tr4eZOQy7E1pQmBPDs4efMp\nBo7GDozpz6C6chr8V+IFPY9ISuDMT4GRpzBhM5ScZxe8Z4WSsvRKuNlZw8Rq6SAV\nT73Em7QsXt4CHDreAaEuH+SDHGITDCzX+yXzgrtgVAECgYEA+C/eQVwTpe4M0ZDk\n5gp92z1T5b1g5igOGOh7SsskEd8S1DemLT/Wma35oE0tusWFBaoiOORx/XWADiH+\n+zKEE0lcrESgOQoj6x+AjktG63dnscrXlFRhDTkchkWR3a+I9gzf7CBGp/St39Dj\nAaHH0cUsQhwYZm/Kggho1shgOMECgYEAy2pHY4gMLWHM2vHnR1g1V3r8isEkkExe\n/wW+DITmTKgSLcsjf7BFflG6LfSDXclq2fsgcUPBt45i0JF1cB+rmaGZpM3hTj5Z\nQWCIA9kwS6Slq2nUTNMEW+LlsLjdA2QfGycAd/mVJw29CyWQBMhyx5+wGXIX1o5c\ngjKCIE8eDmMCgYEAjqfFEsCAMrIgAB1O1MNXEDuyC63NEr4XTE3lAFq/gt48Dmtm\nQ0Acc/1CLNfv3xlFmrnuLdFxjASL9JOp4m1o6UUT1Zkkl2SyvKVA2Yl/XD0oB1PW\nklXl6xnWwX8fltMc4IEJ/MmYk1Xa03lX4kpBdtvk0qMfi1Hajt+Sk1JdrIECgYA3\n+KF2GKxJHH0Szbc24WWkEZpFz8lwzyLgh0L5DOSVuTVvVlMJQoaMsI5LMNmox9BX\n9IrDv8Ig8NPt0eh/lqdQGbA+McxKDEvg+l/St0NbvQ088lzRWsr7QZ60Ftnxoe4R\nOZUebhWFbnlTBN3xAvraRO1eww8eIYQA60b0/vAlQwKBgFuJAbn6Vnu88v5E2v+a\nJUGbVmhz1xKMmHR8ahT8Z86VW+PgtB/CXuXTAcZlJJi36iRR/BQR95SMTTVxHy9t\nu+sGHWChLh8Nzz19uYMA/pcIEy77sPFpLZ7WKIBB2Rg/JpsVZQkog1OdTTqTEdrh\ngJAEHmqiWrHxtJ1MZuVlQyPw\n-----END PRIVATE KEY-----\n"

//const WXNotifyUrl = "http://test_api.twzxjy.com:8000/api/v1/wxpay/callback"
var WXNotifyUrl = "https://api.twzxjy.com/api/v1/wxpay/callback"

type WxPay struct {
	service.Service
}

func (e *WxPay) AppPay(ctx context.Context, req *dto.WxPayReq) (appPayParams *wechat.AppPayParams, err error) {
	payEnv := config2.Get("PAY_ENV").String("")
	if payEnv == "test" {
		WXNotifyUrl = "http://test_api.twzxjy.com:8000/api/v1/wxpay/callback"
	}
	xlog.Infof("AliNotifyUrl bm:%s", WXNotifyUrl)
	// NewClientV3 初始化微信客户端 v3
	//	mchid：商户ID 或者服务商模式的 sp_mchid
	// 	serialNo：商户证书的证书序列号
	//	apiV3Key：apiV3Key，商户平台获取
	//	privateKey：私钥 apiclient_key.pem 读取后的内容
	client, err := wechat.NewClientV3(MchId, SerialNo, APIv3Key, PrivateKey)
	if err != nil {
		return nil, err
	}

	// 启用自动同步返回验签，并定时更新微信平台API证书
	err = client.AutoVerifySign()
	if err != nil {
		return nil, err
	}

	// 打开Debug开关，输出日志，默认是关闭的
	client.DebugSwitch = gopay.DebugOn
	xlog.Pretty(appPayParams)
	if err != nil {
		return nil, err
	}
	// 初始化 BodyMap
	bm := make(gopay.BodyMap)
	bm.Set("appid", AppID).
		Set("mchid", MchId).
		Set("description", req.Description).
		Set("out_trade_no", req.OrderSn).
		Set("time_expire", time.Now().Add(10*time.Minute).Format(time.RFC3339)).
		Set("attach", req.OrderType). //商品类型OnlineOrder，MaterialOrder,LiveOrder
		Set("notify_url", WXNotifyUrl).
		SetBodyMap("amount", func(bm gopay.BodyMap) {
			bm.Set("total", req.TotalAmount).
				Set("currency", "CNY")
		})
	//bm.SetBodyMap("payer", func(bm gopay.BodyMap) {
	//	bm.Set("openid", "oK6tx6P1VlEplEwsLMifLuRImtio")
	//})
	// app

	xlog.Infof("wxpay bm:%+v", bm)
	wxRsp, err := client.V3TransactionApp(ctx, bm)
	if err != nil {
		return nil, err
	}

	//appPayParams.Package = "prepayid=" + wxRsp.Response.PrepayId
	//appPayParams.Package = "prepay_id=" + wxRsp.Response.PrepayId
	//特殊处理
	appPayParams, err = client.PaySignOfApp(AppID, wxRsp.Response.PrepayId)
	//appPayParams.Prepayid = wxRsp.Response.PrepayId
	return appPayParams, nil
}

func (e *WxPay) Notify(ctx *gin.Context, result *wechat.V3DecryptResult) error {
	notifyReq, err := wechat.V3ParseNotify(ctx.Request)
	xlog.Info("notifyReq, err:", notifyReq, err)
	if err != nil {
		return err
	}
	//wxPublicKey 通过 client.WxPublicKey() 获取
	client, err := wechat.NewClientV3(MchId, SerialNo, APIv3Key, PrivateKey)
	if err != nil {
		return err
	}
	wxPublicKey := client.WxPublicKey()
	xlog.Infof("notifyReq, wxPublicKey:%+v", wxPublicKey)
	err = notifyReq.VerifySignByPK(wxPublicKey)
	if err != nil {
		xlog.Error("VerifySignByPK err:", err)
		return err
	}
	// ========异步通知敏感信息解密========
	// 普通支付通知解密
	result, err = notifyReq.DecryptCipherText(APIv3Key)
	if err != nil {
		return err
	}
	return nil
}

func GetOutBoundIP() (ip string, err error) {
	conn, err := net.Dial("udp", "8.8.8.8:53")
	if err != nil {
		xlog.Error(err)
		return
	}
	localAddr := conn.LocalAddr().(*net.UDPAddr)
	fmt.Println(localAddr.String())
	ip = strings.Split(localAddr.String(), ":")[0]
	return
}

// 直接使用接口解密
func DecodeNotify(body []byte) (bool, Result) {
	var prepaymap map[string]interface{}
	_ = json.Unmarshal(body, &prepaymap)

	var prepaymap2 = prepaymap["resource"].(map[string]interface{})
	nonce := prepaymap2["nonce"].(string)
	associatedData := prepaymap2["associated_data"].(string)
	ciphertext := prepaymap2["ciphertext"].(string)

	tx, err := payUtils.DecryptAES256GCM(APIv3Key, associatedData, nonce, ciphertext)
	if err != nil {
		log.Println(err)
		return false, Result{}
	}
	//var datamap map[string]string
	r := Result{}
	_ = json.Unmarshal([]byte(tx), &r)
	return true, r
}

type Result struct {
	TransactionId string  `json:"transaction_id"`
	Amount        Amount1 `json:"amount"`
	OutTradeNo    string  `json:"out_trade_no"`
	Attach        string  `json:"attach"`
}
type Amount1 struct {
	Total float64 `json:"total"`
}
